﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;
using System.Windows;
using System.Windows.Controls;

namespace CuteWallpaperDemo.UI.Windows
{
    public abstract class CustomWindowBase : Window
    {
        public event Action? CloseWindowEvent;
        public event Action? RestoreWindowEvent;
        public event Action? MinimizeWindowEvent;
        public event Action? MaximizeWindowEvent;
        public event Action? ShowSystemMenuEvent;

        protected CustomWindowBase()
        {
            DefaultStyleKey = this.GetType();
            CommandBindings.Add(new CommandBinding(SystemCommands.CloseWindowCommand, OnCloseWindow));
            CommandBindings.Add(new CommandBinding(SystemCommands.MaximizeWindowCommand, OnMaximizeWindow, CanResizeWindow));
            CommandBindings.Add(new CommandBinding(SystemCommands.MinimizeWindowCommand, OnMinimizeWindow, CanMinimizeWindow));
            CommandBindings.Add(new CommandBinding(SystemCommands.RestoreWindowCommand, OnRestoreWindow, CanResizeWindow));
            CommandBindings.Add(new CommandBinding(SystemCommands.ShowSystemMenuCommand, OnShowSystemMenu));
            CommandBindings.Add(new CommandBinding(CustomCommands.WindowDropMoveCommand, OnWindowDropMove));
        }

        private void OnWindowDropMove(object sender, ExecutedRoutedEventArgs e)
        {
            try
            {
                DragMove();
            }
            catch { }
        }

        private void OnRestoreWindow(object sender, ExecutedRoutedEventArgs e)
        {
            if (RestoreWindowEvent != null)
            {
                RestoreWindowEvent.Invoke();
            }

            SystemCommands.RestoreWindow(this);
        }

        private void OnMinimizeWindow(object sender, ExecutedRoutedEventArgs e)
        {
            if (MinimizeWindowEvent != null)
            {
                MinimizeWindowEvent.Invoke();
            }

            SystemCommands.MinimizeWindow(this);
        }

        private void OnMaximizeWindow(object sender, ExecutedRoutedEventArgs e)
        {
            if (MaximizeWindowEvent != null)
            {
                MaximizeWindowEvent.Invoke();
            }

            SystemCommands.MaximizeWindow(this);
        }

        private void OnShowSystemMenu(object sender, ExecutedRoutedEventArgs e)
        {
            if (ShowSystemMenuEvent != null)
            {
                ShowSystemMenuEvent.Invoke();
            }

            var element = e.OriginalSource as FrameworkElement;
            if (element == null) return;

            var point = WindowState == WindowState.Maximized
                ? new Point(0, element.ActualHeight)
                : new Point(Left + BorderThickness.Left, element.ActualHeight + Top + BorderThickness.Top);
            point = element.TransformToAncestor(this).Transform(point);
            SystemCommands.ShowSystemMenu(this, point);
        }


        private void OnCloseWindow(object sender, ExecutedRoutedEventArgs e)
        {
            if (CloseWindowEvent != null)
            {
                CloseWindowEvent.Invoke();
            }

            this.Close();
        }


        protected override void OnContentRendered(EventArgs e)
        {
            base.OnContentRendered(e);
            if (SizeToContent == SizeToContent.WidthAndHeight)
            {
                InvalidateMeasure();
            }
        }

        protected void CanMinimizeWindow(object sender, CanExecuteRoutedEventArgs e)
        {
            e.CanExecute = ResizeMode != ResizeMode.NoResize;
            var btn = sender as Button;
            if (btn != null)
            {
                btn.Visibility = ResizeMode == ResizeMode.NoResize ? Visibility.Collapsed : Visibility.Visible;
            }
        }

        protected void CanResizeWindow(object sender, CanExecuteRoutedEventArgs e)
        {
            e.CanExecute = ResizeMode == ResizeMode.CanResize || ResizeMode == ResizeMode.CanResizeWithGrip;
        }

    }
}
